package org.ztr.yanai.blog.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.ztr.yanai.blog.annotation.RequirePermission;
import org.ztr.yanai.blog.exception.BusinessException;
import org.ztr.yanai.blog.exception.ErrorCode;

import java.lang.reflect.Method;

/**
 * @Author: ZhaoTR
 * @Date: Created in 2025/11/22 14:30
 * @Description: 权限校验切面，拦截需要权限的方法
 * @Version: 1.0
 */
@Slf4j
@Aspect
@Component
public class PermissionAspect {

    /**
     * 定义切点：拦截所有带@RequirePermission注解的方法
     */
    @Pointcut("@annotation(org.ztr.yanai.blog.annotation.RequirePermission)")
    public void permissionPointcut() {
    }

    /**
     * 环绕通知：权限校验
     */
    @Around("permissionPointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        
        // 获取注解
        RequirePermission requirePermission = method.getAnnotation(RequirePermission.class);
        if (requirePermission == null) {
            return joinPoint.proceed();
        }
        
        // 获取需要的权限
        String[] permissions = requirePermission.value();
        String[] roles = requirePermission.roles();
        
        log.info("权限校验 - 需要权限: {}, 需要角色: {}", permissions, roles);
        
        // TODO: 从上下文中获取当前用户信息，校验权限
        // 这里简化处理，实际应该从SecurityContext或ThreadLocal中获取用户信息
        boolean hasPermission = checkPermission(permissions, roles);
        
        if (!hasPermission) {
            log.warn("权限不足，拒绝访问");
            throw new BusinessException(ErrorCode.ACCESS_DENIED);
        }
        
        return joinPoint.proceed();
    }

    /**
     * 检查权限（示例实现，实际应该根据业务需求完善）
     */
    private boolean checkPermission(String[] permissions, String[] roles) {
        // TODO: 实现真实的权限校验逻辑
        // 1. 从SecurityContext或ThreadLocal获取当前用户
        // 2. 查询用户的角色和权限
        // 3. 判断是否拥有所需权限
        
        // 临时返回true，允许所有请求通过
        return true;
    }
}
